import tools from './tools'
const dataDealer = tools.dataDealer

// socket data解密 onmessage时使用
const dataDecryptController = [
  // 特殊情况单独处理群聊id
  {
    name: 'group_id',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 用户/群聊ID
  {
    name: 'id',
    result: null,
    length: 8,
    stop: true,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 用户头像
  {
    name: 'user_img',
    result: null,
    length: 8,
    stop: true,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 用户名
  {
    name: 'user_name',
    result: null,
    onmessage ({ data, firstIndex, length }) {
      if (length) {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, length))
      } else {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
      }
    }
  },
  // 群聊名称
  {
    name: 'group_name',
    result: null,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
    }
  },
  // 群聊头像
  {
    name: 'group_img',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // id类型（1-私聊编号；2-群聊编号）
  {
    name: 'id_type',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 时间戳
  {
    name: 'timestamp',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 请求编号
  {
    name: 'invitation_id',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 消息类型 1. 文本消息 2. 语音消息 3. 图片消息 4. 文件消息
  {
    name: 'msg_type',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 消息长度
  {
    name: 'msg_length',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 文本消息
  {
    name: 'msg',
    result: null,
    onmessage ({ data, firstIndex, length }) {
      if (length) {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, length))
      } else {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
      }
    }
  },
  // 批量接收消息时 不同消息类型解析得到不同的消息
  {
    name: 'type_msg',
    result: null,
    length: null,
    onmessage ({ data, firstIndex, msgType }) {
      switch (msgType) {
        case 1: {
          const msgLength = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 2), 16)
          const msg = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex + 2, msgLength))
          this.length = msgLength + 2
          this.result = {
            msgLength,
            msg
          }
          break
        }
        case 2: {
          const fileId = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 8), 64))
          const voiceLength = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 8, 1), 8)
          this.length = 9
          this.result = {
            fileId,
            voiceLength
          }
          break
        }
        case 3: {
          const imgId = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 8), 64))
          const imgWidth = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 8, 2), 16)
          const imgHeight = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 10, 2), 16)
          this.length = 12
          this.result = {
            imgId,
            imgWidth,
            imgHeight
          }
          break
        }
        case 4: {
          const fileId = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 8), 64))
          const fileSize = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 8, 4), 32)
          const fileNameLength = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 12, 2), 16)
          const fileName = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex + 14, fileNameLength))
          this.length = fileNameLength + 14
          this.result = {
            fileId,
            fileSize,
            fileNameLength,
            fileName
          }
          break
        }
        case 5: {
          const duration = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 4), 32)
          const callType = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 4, 1), 8)
          const callState = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 5, 1), 8)
          this.length = 6
          this.result = {
            duration,
            callType,
            callState
          }
        }
      }
    }
  },
  // 图片ID
  {
    name: 'img_id',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 图片宽度
  {
    name: 'img_width',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 图片高度
  {
    name: 'img_height',
    result: null,
    length: 2,
    // 收到图片消息时不需要进行将result的值赋值给length的操作的标志位
    stop: true,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 文件ID
  {
    name: 'file_id',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 文件大小
  {
    name: 'file_size',
    result: null,
    length: 4,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 32)
    }
  },
  // 文件名长度
  {
    name: 'file_name_length',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 文件名
  {
    name: 'file_name',
    result: null,
    onmessage ({ data, firstIndex, length }) {
      if (length) {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, length))
      } else {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
      }
    }
  },
  // 语音长度
  {
    name: 'voice_length',
    result: null,
    length: 1,
    stop: true,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 通话类型
  {
    name: 'call_type',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 发送方ID
  {
    name: 'from',
    result: null,
    stop: true,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 消息类型 1. 私聊 2. 群聊
  {
    name: 'belong',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 发送单位 群聊编号/发送方ID
  {
    name: 'send_uint',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 消息编号长度
  {
    name: 'id_length',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 消息编号
  {
    name: 'msg_id',
    result: null,
    onmessage ({ data, firstIndex, length }) {
      if (length) {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, length))
      } else {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
      }
    }
  },
  // 会议编号
  {
    name: 'cf_id',
    result: null,
    length: 8,
    stop: true,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 会议号
  {
    name: 'cf_code',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, this.length))
    }
  },
  // p2p消息类型
  {
    name: 'p2p_type',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // p2p消息内容
  {
    name: 'p2p_msg',
    result: null,
    onmessage ({ data, firstIndex, msgType }) {
      switch (msgType) {
        case 1: {
          this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
          break
        }
        case 2: {
          this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
          break
        }
        case 3: {
          this.result = {}
          this.result.candidate_type = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 1), 8)
          this.result.candidate_content = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex + 1))
          break
        }
      }
    }
  },
  // 会议名称长度
  {
    name: 'cf_name_length',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 会议名称
  {
    name: 'cf_name',
    result: null,
    onmessage ({ data, firstIndex, length }) {
      if (length) {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, length))
      } else {
        this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
      }
    }
  },
  // 会议主持人
  {
    name: 'cf_host',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 会议发起人
  {
    name: 'cf_sponsor',
    result: null,
    length: 8,
    onmessage ({ data, firstIndex }) {
      this.result = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 64))
    }
  },
  // 会议开始时间
  {
    name: 'cf_start_time',
    result: null,
    length: 19,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, this.length))
    }
  },
  // 是否锁定会议
  {
    name: 'cf_isLocked',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8))
    }
  },
  // 是否开启全员静音
  {
    name: 'cf_mute_all',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8))
    }
  },
  // 是否关闭所有摄像头
  {
    name: 'cf_close_camera_all',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8))
    }
  },
  // 在会人数
  {
    name: 'cf_member_length',
    result: null,
    length: 2,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 16)
    }
  },
  // 在会人员
  {
    name: 'cf_members',
    result: null,
    length: null,
    onmessage ({ data, firstIndex, length }) {
      this.length = length * 10
      this.result = []
      for (let i = 0; i < length; i++) {
        const id = Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 8), 64))
        const voiced = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 8, 1), 8))
        const camera = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex + 9, 1), 8))
        this.result[i] = {
          id,
          voiced,
          camera
        }
        firstIndex += 10
      }
    }
  },
  // 邀请人员信息
  {
    name: 'cf_invited',
    result: null,
    onmessage ({ data, firstIndex }) {
      if ((data.byteLength - firstIndex) > 0 && (data.byteLength - firstIndex) % 8 === 0) {
        this.result = []
        do {
          this.result.push(Number(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, 8), 64)))
          firstIndex += 8
        } while (firstIndex !== data.byteLength)
      } else {
        this.result = []
      }
    }
  },
  // 会议密码
  {
    name: 'cf_pwd',
    result: null,
    length: 6,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex, this.length))
    }
  },
  // 是否开启麦克风
  {
    name: 'voiced',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8))
    }
  },
  // 是否开启摄像头
  {
    name: 'camera',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = Boolean(dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8))
    }
  },
  // 操作类型（摄像头/麦克风）
  {
    name: 'cf_operation',
    result: null,
    length: 1,
    onmessage ({ data, firstIndex }) {
      this.result = !dataDealer.uint8ToNum(dataDealer.uint8Intercept(data, firstIndex, this.length), 8)
    }
  },
  // 会议消息
  {
    name: 'cf_msg',
    result: null,
    onmessage ({ data, firstIndex }) {
      this.result = dataDealer.uint8ToStr(dataDealer.uint8Intercept(data, firstIndex))
    }
  }
]

// 处理字节数组得到的结果数组
export let resArr = []

// 设置dataDecryptController, 批量解析结果
export const setDataDecryptController = ({ bodyData, nameArr, firstIndex, ifMsgArr }) => {
  let length = 0
  resArr = []
  do {
    if (!ifMsgArr) {
      ifMsgArr = false
    }
    // 该次循环的结果对象
    const res = {}
    // 遍历传入的变量名数组
    for (let i = 0; i < nameArr.length; i++) {
      // 查找与变量名数组当前项匹配的对象
      const controller = dataDecryptController.filter(item => item.name === nameArr[i])[0]
      // 批量解析未读消息时使用
      const msgType = dataDecryptController.filter(item => item.name === 'msg_type')[0].result
      // 处理p2p消息时使用
      const p2pType = dataDecryptController.filter(item => item.name === 'p2p_type')[0].result
      // 调用当前对象的onmessage得到字节数组解析结果
      controller.onmessage({ data: bodyData, firstIndex, length, msgType: msgType | p2pType })
      res[controller.name] = controller.result
      // 如果当前对象中包含length属性
      if (controller.length) {
        // 让下一次解析时字节数组截取起始位置加上当前结果匹配的长度，同时让未知截取长度的长度为当前解析结果
        if (!controller.stop) {
          length = controller.result
        } else {
          length = 0
        }
        firstIndex += controller.length
      } else {
        // 如果当前对象中不包含length属性，则下一次解析时的字节数组截取起始位置加上上一次存储的length长度，这时的length即为当前解析对象的长度，并将length置空
        firstIndex += length
        length = 0
      }
    }
    resArr.push(res)
  } while (firstIndex < bodyData.byteLength && ifMsgArr)
  // 清空result
  dataDecryptController.forEach(item => {
    item.result = null
  })
}
